package com.canyou.datascope;

import com.canyou.enums.DataPermEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.List;

/**
 * 数据权限参数
 * 使用方式为在需要数据权限的mapper接口方法加上DataScope参数, scopeName, scopeIds, dataPermEnum 都可以初始化为不同的值
 * 处理的逻辑如下:
 *  1. DataScope参数如果为null时, 不做数据过滤
 *  2.  2.1. 传入DataScope中dataPermEnum不为null时:
 *  使用dataPermEnum的数据权限类型去构建scopeName(数据范围的查询字段名称)和scopeIds(具体的数据范围)
 *  通常情况下:
 *          数据权限的类型为1(仅本人数据时): scopeName为user_id, scopeIds为当前登录用户的id值
 *          数据权限的类型为2(所在部门数据): scopeName为dept_id, scopeIds为当前登录用户所属部门的id值
 *          数据权限的类型为3(所在部门及下属部门数据): scopeName为dept_id, scopeIds为当前登录用户所属部门及其子部门的id值集合
 *          数据权限的类型为4(所在公司数据): scopeName为org_id, scopeIds为当前登录用户所属公司的id值
 *          数据权限的类型为5(所在公司及以下数据): scopeName为org_id, scopeIds为当前登录用户所属公司及其子公司的id值集合
 *      如果你sql中的查询字段和默认的scopeName不一致, 需要你初始化 DataScope 参数设置对应的查询字段名称. 这时按3条逻辑处理
 *      2.2. 传入的DataScope中dataPermEnum为null时:
 *  获取当前登录用户的所有角色, 找出角色中最大的数据权限来构建scopeName和scopeIds
 *  3. 在scopeName或scopeIds不为null时:
 *      使用初始化的scopeName作为数据范围的查询字段名称
 *      使用初始化的scopeIds作为具体的数据范围
 *
 * 注意: 当与分页一起使用时, DataScope参数必须在分页参数后. 需要做数据权限过滤的表需要加上对应的scope字段
 *
 * @author fy
 * @date 2018-08-08 17:03
 */
@Data
@NoArgsConstructor
@Accessors(chain = true)
public class DataScope {

    /**
     * 限制数据范围的查询字段名称
     * 默认为 org_id 或 dept_id 或 user_id
     */
    private String scopeName;

    /**
     * 具体的数据范围
     */
    private List<Long> scopeIds;

    /**
     * 数据权限类型枚举
     * 数据权限的类型: 数据权限的类型(1. 仅本人数据; 2. 所在部门数据; 3. 所在部门及下属部门数据; 4. 所在公司数据; 5. 所在公司及下属公司数据)
     * 不为null时使用dataPermEnum的数据权限类型去构建scopeName(数据范围的查询字段名称)和scopeIds(具体的数据范围)
     */
    private DataPermEnum dataPermEnum;

    /**
     * 是否启用where条件优化(默认开启)
     *  1. 不开启的话是使用子查询来做数据权限的, 子查询做数据权限有很多局限性,
     *      比如针对 select SUM 或者 group by等等无法实现, 同时对于有order by的select语句进行子查询后顺序无法保证
     *  2. 启用后会使用`jsqlparser`解析合理增加where条件, 但是不保证一定不会报错, 通常情况下不会有问题
     *      因为有一些mysql特有的语句`sqlparser`无法正确解析, 比如`select BINARY`.
     */
    private boolean optimize = true;

}
